package guowei.guliproduct.product.web;

import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/test")
public class TestRedisson {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 测试闭锁 可以用作并行操作等待      例：锁门放假需要5个班的人全部离校，
     */
    @GetMapping("/closedoor")
    public String testCountDown() throws InterruptedException {
        RCountDownLatch countDownLatch = redissonClient.getCountDownLatch("bi-lock");
//计数为5,则await()等待闭锁完成解锁
        countDownLatch.trySetCount(5);
        countDownLatch.await();
        return "关门放假从现在开始";
    }

    @GetMapping("/countDown/{id}")
    public String countDpwnRelease(@PathVariable("id") Long id){
        RCountDownLatch countDownLatch = redissonClient.getCountDownLatch("bi-lock");
//计数减一
        countDownLatch.countDown();
        return id+"班的人走了。。。。";
    }


    /**
     * 测试信号量，可以用作分布式限流
     * @return
     */
    @GetMapping("/semaphore")
    public String testsemaphore(){
        RSemaphore semaphore = redissonClient.getSemaphore("flowrate");
        boolean b = semaphore.tryAcquire();
        if (b){
            return "获得流量成功";
        }else {
            return "获取流量失败";
        }
    }

    @GetMapping("/release")
    public String releaseSemaphore(){
        RSemaphore semaphore = redissonClient.getSemaphore("flowrate");
        semaphore.release();
        return "释放了一个流量";
    }

    /**
     * 测试读写锁，读锁是共享锁，而写锁是排他锁
     * @return
     */
    @GetMapping("/write")
    public String testwritelock(){
        RReadWriteLock lock = redissonClient.getReadWriteLock("wr-lock");
        RLock rLock = lock.writeLock();
        rLock.lock();
        String s = "";
        try {
            s = UUID.randomUUID().toString();
            Thread.sleep(20000);
            stringRedisTemplate.opsForValue().set("kk",s);
        }catch (Exception e){
            throw new RuntimeException(e);
        }finally {
            rLock.unlock();
        }
        return s;
    }

    @GetMapping("/read")
    public String testReadlock(){
        RReadWriteLock lock = redissonClient.getReadWriteLock("wr-lock");
        RLock rLock = lock.readLock();
        rLock.lock();
        String s = "";
        try {
            s = stringRedisTemplate.opsForValue().get("kk");
        } finally {
            rLock.unlock();
        }
        return s;
    }


//测试redisson的加锁与解锁 不带过期时间与带过期时间的
    @GetMapping("/hello")
    public String hello(){
        RLock lock = redissonClient.getLock("my-lock");
        lock.lock(10,TimeUnit.SECONDS);
        System.out.println("当前线程是"+Thread.currentThread().getId());
        try {
            Thread.sleep(30000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            System.out.println("释放锁。。。");
            lock.unlock();
        }
        return "hello";
        }
    }
